package smallChanges.lineNumberMapping;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import smallChanges.statements.ClassDeclaration;
import smallChanges.statements.FieldDeclarationStatement;
import smallChanges.statements.MethodDeclarationStatement;
import smallChanges.statements.Statement;
import smallChanges.statements.StatementList;

public class ClassSource {
	
	private ClassDeclaration classDecl;
	private HashMap<String, MethodDeclarationStatement> methodDecls;
	private HashMap<String, FieldDeclarationStatement> fieldDecls;
	private StatementList staticInitializer;
	private HashMap<String, ClassSource> innerClassSources;
	
	public ClassSource()
	{
		methodDecls = new HashMap<String, MethodDeclarationStatement>();
		fieldDecls = new HashMap<String, FieldDeclarationStatement>();
		innerClassSources = new HashMap<String, ClassSource> (); 
	}

	public Iterator<MethodDeclarationStatement> getMethodDeclarationIterator()
	{
	    return methodDecls.values().iterator();
	}
	
	public String getClassName()
	{
		return classDecl.getName();
	}
	
	public FieldDeclarationStatement getFieldDecl(String name)
	{
		return fieldDecls.get(name);
	}
	
	public void addMethodDecl(String sig, MethodDeclarationStatement methodDecl)
	{
		methodDecls.put(sig, methodDecl);
	}
	
	public void addFieldDecl(String sig, FieldDeclarationStatement fieldDecl)
	{
		fieldDecls.put(sig, fieldDecl);
	}
	
	public void addInnerClassSource(String sig, ClassSource classDecl)
	{
		innerClassSources.put(sig, classDecl);
	}
	
	public StatementList getStaticInitializer() {
		return staticInitializer;
	}

	public void setStaticInitializer(StatementList staticInitializer) {
		this.staticInitializer = staticInitializer;
	}

	public MethodDeclarationStatement getMethodDeclarationStatement(String sig)
	{
	    return methodDecls.get(sig);
	}
	
	public Iterator<String> getMethodSignatureIterator()
	{
		return methodDecls.keySet().iterator();
	}

	public Iterator<String> getFieldNameIterator()
	{
		return fieldDecls.keySet().iterator();
	}
	
	public Iterator<String> getInnerClassNameIterator()
	{
		return innerClassSources.keySet().iterator();
	}
	
	public ClassSource getInnerClass(String sig)
	{
		return innerClassSources.get(sig);
	}
	
	public ArrayList<String> getCleanedOutMethodBody(String methodSignature, ArrayList<Statement> statements)
	{
		ArrayList<String> methodBody  = new ArrayList<String>();

		try
		{
			MethodDeclarationStatement methodDeclStmt = methodDecls.get(methodSignature);
			List<Statement> innerList=methodDeclStmt.flatten();
			int i;
			for( i=0;i<methodDeclStmt.getBeginLine();i++)
			{
				methodBody.add("");
			}
			for (Statement s : innerList) {
				statements.add(s);
				methodBody.add(s.getImage());

				i++;
			}
			return methodBody;

		}catch(Exception e)
		{
			return null;
		}
	}

	public int getStaticInitializerStartLine()
	{
		return staticInitializer.getBeginLine();
	}
	
	public ArrayList<String> getStaticInitializerStatements(ArrayList<Statement> statements)
	{
		ArrayList<String> body  = new ArrayList<String>();

		try
		{
			List<Statement> innerList=staticInitializer.flatten();
			int i;
			for( i=0;i<staticInitializer.getBeginLine();i++)
			{
				body.add("");
			}
			for (Statement s : innerList) {
				statements.add(s);
				body.add(s.getImage());

				i++;
			}
			return body;

		}catch(Exception e)
		{
			return null;
		}
	}

	public int getMethodStartLine(String methodSignature)
	{
		return methodDecls.get(methodSignature).getBeginLine();
	}

	public ClassDeclaration getClassDecl() {
		return classDecl;
	}

	public void setClassDecl(ClassDeclaration classDecl) {
		this.classDecl = classDecl;
	}
}
